// frontend/utils/component-optimizer.js
/**
 * 组件优化工具 🚀
 * 
 * 提供组件渲染性能优化功能，包括组件懒加载、虚拟列表、渲染优化等
 */

import { performanceMonitor } from './performance-monitor';

/**
 * 组件懒加载包装器
 * @param {Function} importFunc - 动态导入函数
 * @param {Object} options - 配置选项
 * @returns {Object} 懒加载组件
 */
export function lazyLoad(importFunc, options = {}) {
  const defaultOptions = {
    loading: null,
    error: null,
    delay: 200,
    timeout: 30000,
    ...options
  };
  
  // 记录组件加载性能
  const componentName = options.name || 'UnknownComponent';
  
  return {
    // 异步加载组件
    component: () => {
      const startTime = performance.now();
      
      return importFunc()
        .then(component => {
          const loadTime = performance.now() - startTime;
          
          // 记录组件加载时间
          performanceMonitor.metrics.components = performanceMonitor.metrics.components || {};
          performanceMonitor.metrics.components[componentName] = {
            loadTime,
            timestamp: new Date().toISOString()
          };
          
          return component;
        })
        .catch(error => {
          console.error(`Failed to load component ${componentName}:`, error);
          throw error;
        });
    },
    loading: defaultOptions.loading,
    error: defaultOptions.error,
    delay: defaultOptions.delay,
    timeout: defaultOptions.timeout
  };
}

/**
 * 防抖函数
 * @param {Function} func - 要防抖的函数
 * @param {number} wait - 等待时间（毫秒）
 * @returns {Function} 防抖后的函数
 */
export function debounce(func, wait = 300) {
  let timeout;
  
  return function executedFunction(...args) {
    const later = () => {
      clearTimeout(timeout);
      func(...args);
    };
    
    clearTimeout(timeout);
    timeout = setTimeout(later, wait);
  };
}

/**
 * 节流函数
 * @param {Function} func - 要节流的函数
 * @param {number} limit - 限制时间（毫秒）
 * @returns {Function} 节流后的函数
 */
export function throttle(func, limit = 300) {
  let inThrottle;
  
  return function executedFunction(...args) {
    if (!inThrottle) {
      func(...args);
      inThrottle = true;
      setTimeout(() => {
        inThrottle = false;
      }, limit);
    }
  };
}

/**
 * 虚拟列表类
 * 用于高效渲染大型列表
 */
export class VirtualList {
  /**
   * 创建虚拟列表
   * @param {Object} options - 配置选项
   * @param {Array} options.items - 列表项数组
   * @param {number} options.itemHeight - 每项高度
   * @param {number} options.visibleItems - 可见项数量
   * @param {Function} options.renderItem - 渲染项函数
   */
  constructor(options) {
    this.options = {
      items: [],
      itemHeight: 50,
      visibleItems: 10,
      renderItem: item => item,
      ...options
    };
    
    this.scrollTop = 0;
    this.startIndex = 0;
    this.endIndex = 0;
    this.visibleItems = [];
    this.totalHeight = 0;
    
    this.updateVisibleItems();
  }
  
  /**
   * 更新可见项
   * @param {number} scrollTop - 滚动位置
   */
  updateVisibleItems(scrollTop = this.scrollTop) {
    this.scrollTop = scrollTop;
    
    // 计算起始索引
    this.startIndex = Math.floor(scrollTop / this.options.itemHeight);
    
    // 计算结束索引
    this.endIndex = Math.min(
      this.startIndex + this.options.visibleItems * 2, // 多渲染一些项以提高滚动体验
      this.options.items.length - 1
    );
    
    // 获取可见项
    this.visibleItems = this.options.items.slice(this.startIndex, this.endIndex + 1);
    
    // 计算总高度
    this.totalHeight = this.options.items.length * this.options.itemHeight;
    
    // 计算顶部偏移
    this.topOffset = this.startIndex * this.options.itemHeight;
  }
  
  /**
   * 处理滚动事件
   * @param {Event} event - 滚动事件
   */
  handleScroll(event) {
    const scrollTop = event.target.scrollTop;
    this.updateVisibleItems(scrollTop);
  }
  
  /**
   * 获取列表容器样式
   * @returns {Object} 样式对象
   */
  getContainerStyle() {
    return {
      height: `${this.options.visibleItems * this.options.itemHeight}px`,
      overflowY: 'auto',
      position: 'relative'
    };
  }
  
  /**
   * 获取列表内容样式
   * @returns {Object} 样式对象
   */
  getContentStyle() {
    return {
      height: `${this.totalHeight}px`,
      position: 'relative'
    };
  }
  
  /**
   * 获取列表项样式
   * @param {number} index - 项索引
   * @returns {Object} 样式对象
   */
  getItemStyle(index) {
    return {
      position: 'absolute',
      top: `${(this.startIndex + index) * this.options.itemHeight}px`,
      height: `${this.options.itemHeight}px`,
      left: 0,
      right: 0
    };
  }
  
  /**
   * 渲染虚拟列表
   * @returns {Object} 渲染数据
   */
  render() {
    return {
      containerStyle: this.getContainerStyle(),
      contentStyle: this.getContentStyle(),
      visibleItems: this.visibleItems.map((item, index) => ({
        item,
        style: this.getItemStyle(index),
        rendered: this.options.renderItem(item, this.startIndex + index)
      })),
      handleScroll: this.handleScroll.bind(this)
    };
  }
}

/**
 * 记忆化函数
 * @param {Function} func - 要记忆化的函数
 * @returns {Function} 记忆化后的函数
 */
export function memoize(func) {
  const cache = new Map();
  
  return function(...args) {
    const key = JSON.stringify(args);
    
    if (cache.has(key)) {
      return cache.get(key);
    }
    
    const result = func.apply(this, args);
    cache.set(key, result);
    
    return result;
  };
}

/**
 * 组件渲染优化HOC
 * @param {Object} Component - 要优化的组件
 * @param {Object} options - 配置选项
 * @returns {Object} 优化后的组件
 */
export function optimizeComponent(Component, options = {}) {
  const defaultOptions = {
    name: Component.name || 'OptimizedComponent',
    shouldUpdate: (prevProps, nextProps) => {
      // 默认浅比较
      if (Object.keys(prevProps).length !== Object.keys(nextProps).length) {
        return true;
      }
      
      for (const key in nextProps) {
        if (prevProps[key] !== nextProps[key]) {
          return true;
        }
      }
      
      return false;
    },
    ...options
  };
  
  // 创建优化后的组件
  const OptimizedComponent = {
    name: defaultOptions.name,
    props: Component.props,
    
    render(h) {
      return h(Component, {
        props: this.$props,
        attrs: this.$attrs,
        on: this.$listeners,
        scopedSlots: this.$scopedSlots
      });
    },
    
    beforeUpdate() {
      const startTime = performance.now();
      this.$_updateStartTime = startTime;
    },
    
    updated() {
      if (this.$_updateStartTime) {
        const updateTime = performance.now() - this.$_updateStartTime;
        
        // 记录组件更新时间
        performanceMonitor.metrics.componentUpdates = performanceMonitor.metrics.componentUpdates || {};
        performanceMonitor.metrics.componentUpdates[defaultOptions.name] = {
          updateTime,
          timestamp: new Date().toISOString()
        };
      }
    }
  };
  
  return OptimizedComponent;
}

/**
 * 创建一个只在可见时渲染的组件
 * @param {Object} options - 配置选项
 * @returns {Object} 组件配置
 */
export function createVisibilityObserver(options = {}) {
  const defaultOptions = {
    threshold: 0.1, // 可见阈值
    rootMargin: '0px',
    ...options
  };
  
  return {
    data() {
      return {
        isVisible: false,
        observer: null
      };
    },
    
    mounted() {
      // 创建交叉观察器
      this.observer = new IntersectionObserver(entries => {
        const entry = entries[0];
        this.isVisible = entry.isIntersecting;
      }, {
        threshold: defaultOptions.threshold,
        rootMargin: defaultOptions.rootMargin
      });
      
      // 开始观察
      this.observer.observe(this.$el);
    },
    
    beforeDestroy() {
      // 停止观察
      if (this.observer) {
        this.observer.disconnect();
        this.observer = null;
      }
    }
  };
}

/**
 * 批量更新DOM
 * @param {Function} updateFunc - 更新函数
 */
export function batchUpdate(updateFunc) {
  // 使用requestAnimationFrame在下一帧更新
  requestAnimationFrame(() => {
    updateFunc();
  });
}

// 导出所有工具
export default {
  lazyLoad,
  debounce,
  throttle,
  VirtualList,
  memoize,
  optimizeComponent,
  createVisibilityObserver,
  batchUpdate
};